package org.lonetree.tc.core.id;


/**
 * A NumericalId is an encapsulation of a numerical identifier (a number that
 * can be used to, for example, uniquely identify an InternalIdentifiableItem).
 */
public abstract class NumericalId extends ValidatedIdentifier{

	protected static final int INFINITE_LENGTH_ALLOWED = -1;
	
	/**
	 * Create a NumericalId.
	 *
	 * @param numericalId the number representing the ID
	 * @param stringLength the length that the ID is supposed to be when printed as a String. If numericalId is greater in value than stringLength allows, a ValidationException will be thrown. If it is too short, it will be padded with 0s. If stringLength is INFINITE_LENGTH_ALLOWED, the length of numericalId will not be checked and it will not be padded with any zeros.
	 * @throws ValidationException if the ID is malformed
	 */
	protected NumericalId(long numericalId, int stringLength) throws ValidationException{
		super(checkAndPossiblyPad(numericalId, stringLength));
	}
	
	private static String checkAndPossiblyPad(long numericalId, int stringLength) throws ValidationException{
		String numIdStr = numericalId + "";
		
		if(stringLength != INFINITE_LENGTH_ALLOWED){
			int pad = stringLength - numIdStr.length();
			if(pad < 0)
				throw new ValidationException("numericalId is too large (it is constrained to " + stringLength + " digits by stringLength");
			
			for(int i = 0; i<pad; i++){
				numIdStr = "0" + numIdStr;
			}
		}
		
		return numIdStr;
	}

	protected NumericalId(String numericalId) throws ValidationException{
		super(numericalId);
	}

	@Override
	protected String validateAndFix(String identifier) throws ValidationException{
		try{
			Long.parseLong(identifier);
			return identifier;
		}
		catch(NumberFormatException e){
			throw new ValidationException("numericalId must be a parsable number", e);
		}
	}
	
	protected Long getNumericalIdLong(){
		return new Long(getIdentifierString());
	}
}
